--- kind: dependency_management name: 多构建体系下的依赖管理:ESP-IDF Component Manager、MicroPython Manifest与Sphinx requirements category: dependency_management scope: - '**' source_files: - esp32s3/firmware/main/idf_component.yml - esp32s3/firmware/components/esp_lcd_jd9853/idf_component.yml - esp32s3/firmware/components/gen_bmgr_codes/idf_component.yml - esp32s3/firmware/boards/manifest.py - esp32s3/firmware/boards/mpython_v3/manifest.py - firmware/port/boards/manifest.py - esp32s3/firmware/eim_config.toml - esp32s3/docs/requirements.txt - firmware/port/Makefile --- # 1. 使用的系统与工具 本仓库同时维护两套固件(firmware/port/ 基于 ESP32 MicroPython port;esp32s3/firmware/ 基于 ESP-IDF v5.x + MicroPython v1.24.1)以及 Sphinx 文档,因此存在三套并行的依赖声明机制: - **ESP-IDF Component Manager**(`idf_component.yml`):用于 esp32s3/firmware 的 C/C++ 组件依赖,通过 `espressif/xxx` 命名空间从 Espressif 官方组件仓库拉取。 - **MicroPython frozen manifest**(`manifest.py` / `mpconfigboard.mk`):用于将 Python 模块编译进固件镜像(frozen bytecode),控制运行时可用的标准库与第三方包。 - **Sphinx 文档依赖**(`docs/requirements.txt`):锁定构建文档所需的 Python 包版本。 此外,`esp32s3/firmware/eim_config.toml` 使用 EIM(Espressif Install Manager)配置 IDF 工具链、Python 环境及 PyPI 镜像源(清华 tuna),实现本地化下载加速。 # 2. 关键文件与位置 | 层次 | 关键文件 | 作用 | |---|---|---| | S3 固件顶层 | `esp32s3/firmware/main/idf_component.yml` | 声明 ESP-IDF 组件依赖(mdns、tinyusb、esp-sr、esp_audio_codec、esp_video_codec、esp32-camera、joltwallet/littlefs、esp_websocket_client 等) | | S3 自定义组件 | `esp32s3/firmware/components/esp_lcd_jd9853/idf_component.yml` | 屏幕驱动组件,声明对 `cmake_utilities` 和 `idf >= 4.4` 的依赖 | | S3 代码生成组件 | `esp32s3/firmware/components/gen_bmgr_codes/idf_component.yml` | 依赖 `compents/esp_lcd_jd9853: 2.0.2` | | S3 板级 manifest | `esp32s3/firmware/boards/*/manifest.py` | 通过 `include("$(PORT_DIR)/boards/manifest.py")` 复用基础包集合,再 `freeze("modules")` 引入板载 Python 模块 | | S3 基础 manifest | `esp32s3/firmware/boards/manifest.py` | 启用 `bundle-networking`、`aioespnow`、`dht`、`ds18x20`、`onewire`、`upysh`、`collections` 等 MicroPython 包 | | ESP32 端口 manifest | `firmware/port/boards/manifest.py` | 冻结 `$(PORT_DIR)/modules` 与 `$(BOARD_DIR)/modules` 到固件 | | 文档依赖 | `esp32s3/docs/requirements.txt` | 锁定 Sphinx、Jupyter、PyQt、NumPy 等 276 个包的精确版本 | | 工具链配置 | `esp32s3/firmware/eim_config.toml` | 指定 IDF 路径、工具链目录、PyPI 镜像(`https://pypi.tuna.tsinghua.edu.cn/simple`)、IDF 镜像(`https://jihulab.com/esp-mirror`) | | 构建脚本 | `firmware/port/Makefile` | 强制要求 `ESPIDF` 环境变量指向受支持的 git hash(v3.3.2 或 v4.0.1),并通过 `make submodules` 初始化子模块 | # 3. 架构与约定 ## 3.1 组件来源分层 - **官方组件**:通过 `espressif/xxx` 命名空间引用,版本号采用语义化约束(`~1.1.0`、`^2.0`、`==1.5.4`、`>=5.2.0` 等)。例如 `espressif/mdns: ~1.1.0`、`espressif/esp32-camera: ^2.0`。 - **Git 分支覆盖**:`tinyusb` 通过 `git: https://github.com/micropython/tinyusb-espressif.git` + `version: cherrypick/dwc2_zlp_fix` 临时绕过 upstream issue #3154,体现“以补丁分支替代上游版本”的策略。 - **本地 override_path**:GMF(Graphics & Multimedia Framework)相关组件(`gmf_loader`、`gmf_app_utils`、`esp_capture`、`esp_board_manager`、`gmf_core`、`gmf_io`、`gmf_audio`、`gmf_ai_audio`、`gmf_video`、`gmf_misc`、`esp_audio_render`)全部通过 `override_path: ../../esp-gmf/...` 指向外部 Git 子模块,不经过组件仓库。 - **第三方组件**:`joltwallet/littlefs: ==1.20.4` 作为文件系统后端被精确锁定。 ## 3.2 MicroPython 包冻结策略 - 基础网络栈通过 `require("bundle-networking")` 批量引入。 - 传感器/通信协议(`dht`、`ds18x20`、`onewire`、`aioespnow`)通过 `require()` 显式声明。 - 板级 Python 模块通过 `freeze("modules")` 将 `esp32s3/firmware/modules/` 中的 `.py` 文件编译进固件,形成运行时可用模块(如 `ai_cloud.py`、`ATGM336H_5N.py`、`neopixel.py`、`weather.py`、`xunfei.py` 等)。 - ESP32 端口(`firmware/port/`)同样通过 `manifest.py` 冻结 `port/modules` 与 `port/boards//modules`。 ## 3.3 文档依赖锁定 `esp32s3/docs/requirements.txt` 是典型的 pip freeze 产物,包含 276 行精确版本(如 `Sphinx @ file:///...`、`PyQt==1.9.0`、`numpy @ file:///...`),其中大量条目使用 `@ file:///` 形式指向 CI 构建缓存中的 wheel,说明该文件主要用于 CI 复现而非开发者本地安装。实际开发中应配合 `python -m venv` 与 `pip install -r requirements.txt` 使用。 ## 3.4 工具链与镜像 `eim_config.toml` 明确配置了国内镜像: - `mirror = "https://dl.espressif.cn/github_assets"` - `idf_mirror = "https://jihulab.com/esp-mirror"` - `pypi_mirror = "https://pypi.tuna.tsinghua.edu.cn/simple"` 这确保 IDF 工具链、Python 包和 GitHub Assets 均从国内镜像下载,提升构建速度。 # 4. 约定与约束 - **ESP-IDF 版本锁定**:`firmware/port/Makefile` 通过 `ESPIDF_SUPHASH_V3` / `ESPIDF_SUPHASH_V4` 硬编码受支持的 IDF commit hash,并在构建时校验当前 IDF 的 git hash,不匹配则输出 WARNING 并继续(非致命错误)。 - **Python 版本约束**:ESP32 端口要求 `pyparsing==2.3.1`(<2.4),否则直接报错退出;S3 端口在 `eim_config.toml` 中指定 `python_version_override = "python313"`。 - **子模块管理**:README 明确要求 `git clone --recursive` 与 `make submodules`,GMF 相关组件通过 `override_path` 指向外部 `esp-gmf` 子模块,需独立维护。 - **私有/本地组件隔离**:所有 GMF 组件通过 `override_path` 指向本地路径,避免混入公共组件仓库,便于内部迭代。 - **upip 未启用**:`manifest.py` 中 `upip.py` 的 freeze 调用被注释掉,表明固件不包含远程包管理器,依赖需在构建期冻结进镜像。 - **无 vendored 第三方源码**:除 `lib/decode_png`、`lib/utils` 等少量自研 lib 外,未发现 `vendor/` 目录;第三方 C 组件一律通过 ESP-IDF Component Manager 拉取。 - **文档与固件解耦**:`docs/requirements.txt` 仅用于 Sphinx 构建,不影响固件编译;固件依赖集中在 `idf_component.yml` 与 `manifest.py` 两个文件中。